package config;

import cn.hutool.core.util.StrUtil;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.Connection;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Redis Cluster 配置
 *
 * @Author: AllWe
 * @Date: 2024/07/30/10:00
 */
@Configuration
@PropertySource("classpath:application_redisCluster.properties")
public class RedisClusterConfig {

    @Value("${redis.cluster.nodes}")
    private String hosts;

    @Value("${redis.cluster.max-redirects}")
    private int maxRedirects;

    @Value("${redis.cluster.pool.maxTotal}")
    private int maxTotal;

    @Value("${redis.cluster.pool.maxIdle}")
    private int maxIdle;

    @Value("${redis.cluster.pool.maxWaitMillis}")
    private int maxWaitMillis;

    @Value("${redis.timeout}")
    private int timeout;

    @Value("${redis.blockWhenExhausted}")
    private Boolean blockWhenExhausted;

    @Value("${redis.JmxEnabled}")
    private Boolean jmxEnable;

    @Value("${redis.testOnBorrow}")
    private Boolean testOnBorrow;

    @Value("${redis.testOnReturn}")
    private Boolean testOnReturn;

    @Value("${redis.soTimeOut}")
    private int soTimeOut;

    @Value("${redis.maxAttempts}")
    private int maxAttempts;

    @Bean
    public GenericObjectPoolConfig<Connection> genericObjectPoolConfig() {
        GenericObjectPoolConfig<Connection> genericObjectPoolConfig = new GenericObjectPoolConfig<>();
        genericObjectPoolConfig.setMaxTotal(maxTotal);
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMaxWaitMillis(maxWaitMillis);
        genericObjectPoolConfig.setTestOnBorrow(testOnBorrow);
        genericObjectPoolConfig.setTestOnReturn(testOnReturn);
        genericObjectPoolConfig.setJmxEnabled(jmxEnable);
        genericObjectPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        return genericObjectPoolConfig;
    }

    // 配置 JedisCluster
    @Bean
    public JedisCluster getJedisCluster() {
        // 处理redis集群节点集合
        Set<HostAndPort> nodeSet = new HashSet<>();
        if (StrUtil.isNotBlank(hosts)) {
            nodeSet = Arrays.stream(hosts.split(",")).map(n -> {
                String host = n.split(":")[0].trim();
                int port = Integer.parseInt(n.split(":")[1].trim());

                return new HostAndPort(host, port);
            }).collect(Collectors.toSet());
        }
        // 配置JedisCluster参数
        return new JedisCluster(nodeSet, timeout, soTimeOut, maxAttempts, genericObjectPoolConfig());
    }
}
